#ifndef __SERVERCAL_HPP__
#define __SERVERCAL_HPP__
#include <iostream>
#include <cassert>
#include "Protocol.hpp"

enum
{
    DivZeroErr = 1,
    ModZeroErr,
    LabelErr
};

class ServerCal
{
public:
    Response calculatorHelper(Request &req)
    {
        Response rsp(0, 0);

        switch (req.op)
        {
        case '+':
            rsp.result = req.x + req.y;
            break;

        case '-':
            rsp.result = req.x - req.y;
            break;

        case '*':
            // 使用局部作用域
            {
                if (req.x && req.y)
                {
                    rsp.result = req.x * req.y;
                }
                else
                {
                    rsp.code = DivZeroErr;
                }
            }
            break;

        case '/':
            rsp.result = req.x / req.y;
            break;

        case '%':
            // 使用局部作用域
            {
                if (req.x && req.y)
                {
                    rsp.result = req.x % req.y;
                }
                else
                {
                    rsp.code = ModZeroErr;
                }
            }
            break;

        default:
            rsp.code = LabelErr;
            std::cout << "error in label" << std::endl;
            break;
        }

        return rsp;
    }

    //"7""10 + 10"
    std::string calculator(std::string &package)
    {
        Request req;
        //去报头
        std::string content;
        bool r = Decode(package, &content);
        if(!r) return "";
        //反序列化
        r = req.Deserialize(content);
        // std::cout << req.x << " ";
        // std::cout << req.op << " ";
        // std::cout << req.y << std::endl;

        if(!r) return "";

        Response rsp = calculatorHelper(req);
        // std::cout << rsp.result << " ";
        // std::cout << rsp.code << std::endl;
        // package = "";  // 不要在这里动原始数据，在Decode函数内部就已经对于原始数据进行处理了
        //序列化
        std::string content_rsp;
        rsp.serialize(&content_rsp);

        //封装报头
        std::string ret;
        r = Encode(content_rsp, &ret);  // 原则上Encode不需要两个参数，但是为了减少你的代码修改，我在这里就迎合你的Encode实现了
        // std::cout<< content <<std::endl;
        assert(r);
        
        return ret;
    }
};

#endif